// dexviewDlg.cpp : implementation file
//

#include "stdafx.h"
#include "dexview.h"
#include "dexviewDlg.h"
#include "../common/DexScan.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDexviewDlg dialog

CDexviewDlg::CDexviewDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CDexviewDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDexviewDlg)
	m_csfilename = _T("");
	m_pfile = NULL;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CDexviewDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDexviewDlg)
	DDX_Control(pDX, IDC_LIST_DATA, m_listData);
	DDX_Control(pDX, IDC_TREE_DATA, m_treetype);
	DDX_Text(pDX, IDC_EDIT_FILENAME, m_csfilename);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CDexviewDlg, CDialog)
	//{{AFX_MSG_MAP(CDexviewDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_NOTIFY(NM_CLICK, IDC_TREE_DATA, OnClickTreeData)
	ON_NOTIFY(NM_DBLCLK, IDC_TREE_DATA, OnDblclkTreeData)
	ON_BN_CLICKED(IDC_BN_OPEN, OnBnOpen)
	ON_BN_CLICKED(IDC_BN_Close, OnBNClose)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDexviewDlg message handlers

BOOL CDexviewDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here

	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CDexviewDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CDexviewDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CDexviewDlg::OnClickTreeData(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	
	LPNMITEMACTIVATE pNMItemActivate = (LPNMITEMACTIVATE)pNMHDR;
	HTREEITEM   item = m_treetype.GetSelectedItem();
	CString stritem = m_treetype.GetItemText(item);
	*pResult = 0;
}

void CDexviewDlg::OnDblclkTreeData(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
 	LPNMITEMACTIVATE pNMItemActivate = (LPNMITEMACTIVATE)pNMHDR;
 	HTREEITEM   item = m_treetype.GetSelectedItem();
 	int datatype = m_treetype.GetItemData(item);
 	switch (datatype)
 	{
 	case kDexTypeHeaderItem:
 		{
 			ShowHeader();
 		}
 		break;
	case kDexTypeStringIdItem:
 		{
			ShowDexStringId();
 		}
		break;
	case kDexTypeTypeIdItem:
 		{
			ShowDexTypeId();
 		}
		break;
	case kDexTypeMethodIdItem:
		{
			ShowDexMethodId();
		}
		break;
	case kDexTypeClassDefItem:
		{
			ShowDexClassDef(item);
		}
		break;
	case kDexTypeFieldIdItem:
		{
			ShowDexFieldId();
		}
		break;
	case kDexTypeClassDataItem:
		{
			ShowDexClassHeader(item);
		}
		break;
	case kDexTypeProtoIdItem:
		{
			ShowDexProtoId();
		}
		break;
	case kDexTypestaticFieldItem:
		{
			ShowStaticField(item);
		}
		break;
	case kDexTypeinstanceFieldItem:
		{
			ShowInstanceField(item);
		}
		break;
	case kDexTypedirectMethodItem:
		{
			ShowDirectMethod(item);
		}
		break;
	case kDexTypevirtualMethodItem:
		{
			ShowVirtualMethod(item);
		}
		break;
 	default:
 		break;
 	}
	*pResult = 0;
}
int CDexviewDlg::ShowHeader()
{
 	DexHeader header;
 	ReadDexHeader(m_pfile,&header);
 	m_listData.DeleteAllItems();
 	int ColumnCount = m_listData.GetHeaderCtrl()->GetItemCount();
 	for (int i =ColumnCount-1;i>=0;i--)
 	{
 		m_listData.DeleteColumn(i);
 	}	
 	m_listData.InsertColumn(0,TEXT("offset"),LVCFMT_LEFT,90);
 	m_listData.InsertColumn(1,TEXT("name"),LVCFMT_LEFT,90);
 	m_listData.InsertColumn(2,TEXT("value"),LVCFMT_LEFT,200);
	int dwCurrentIndex=0;
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.magic[0]-(DWORD)&header),
		"magic",(char*)header.magic);
	char sztempdata[100] = {0};
	sprintf(sztempdata,"0x%X",header.checksum);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.checksum-(DWORD)&header),
		"checksum",sztempdata);
	for (int j =0;j<kSHA1DigestLen;j++)
	{
		sprintf(&sztempdata[j*2],"%02X",header.signature[j]);
	}
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.signature-(DWORD)&header),
		"signature",sztempdata);
	sprintf(sztempdata,"0x%X",header.fileSize);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.fileSize-(DWORD)&header),
		"fileSize",sztempdata);
	sprintf(sztempdata,"0x%X",header.headerSize);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.headerSize-(DWORD)&header),
		"headerSize",sztempdata);
	sprintf(sztempdata,"0x%X",header.endianTag);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.endianTag-(DWORD)&header),
		"endianTag",sztempdata);
	sprintf(sztempdata,"0x%X",header.linkSize);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.linkSize-(DWORD)&header),
		"linkSize",sztempdata);
	sprintf(sztempdata,"0x%X",header.linkOff);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.linkOff-(DWORD)&header),
		"linkOff",sztempdata);
	sprintf(sztempdata,"0x%X",header.mapOff);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.mapOff-(DWORD)&header),
		"mapOff",sztempdata);
	sprintf(sztempdata,"0x%X",header.stringIdsSize);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.stringIdsSize-(DWORD)&header),
		"stringIdsSize",sztempdata);
	sprintf(sztempdata,"0x%X",header.stringIdsOff);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.stringIdsOff-(DWORD)&header),
		"stringIdsOff",sztempdata);
	sprintf(sztempdata,"0x%X",header.typeIdsSize);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.typeIdsSize-(DWORD)&header),
		"typeIdsSize",sztempdata);
	sprintf(sztempdata,"0x%X",header.typeIdsOff);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.typeIdsOff-(DWORD)&header),
		"typeIdsOff",sztempdata);
	sprintf(sztempdata,"0x%X",header.protoIdsSize);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.protoIdsSize-(DWORD)&header),
		"protoIdsSize",sztempdata);
	sprintf(sztempdata,"0x%X",header.protoIdsOff);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.protoIdsOff-(DWORD)&header),
		"protoIdsOff",sztempdata);
	sprintf(sztempdata,"0x%X",header.fieldIdsSize);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.fieldIdsSize-(DWORD)&header),
		"fieldIdsSize",sztempdata);
	sprintf(sztempdata,"0x%X",header.fieldIdsOff);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.fieldIdsOff-(DWORD)&header),
		"fieldIdsOff",sztempdata);
	sprintf(sztempdata,"0x%X",header.methodIdsSize);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.methodIdsSize-(DWORD)&header),
		"methodIdsSize",sztempdata);
	sprintf(sztempdata,"0x%X",header.methodIdsOff);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.methodIdsOff-(DWORD)&header),
		"methodIdsOff",sztempdata);
	sprintf(sztempdata,"0x%X",header.classDefsSize);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.classDefsSize-(DWORD)&header),
		"classDefsSize",sztempdata);
	sprintf(sztempdata,"0x%X",header.classDefsOff);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.classDefsOff-(DWORD)&header),
		"classDefsOff",sztempdata);
	sprintf(sztempdata,"0x%X",header.dataSize);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.dataSize-(DWORD)&header),
		"dataSize",sztempdata);
	sprintf(sztempdata,"0x%X",header.dataOff);
	insertValue(dwCurrentIndex++,DWORD((DWORD)&header.dataOff-(DWORD)&header),
		"dataOff",sztempdata);
	return 0;
}

void ConvertASIToUncode(char* strasi,wchar_t *struncode)  
{
	int len=MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strasi, -1, NULL,0);
	memset(struncode, 0, len * 2 + 2);
	MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strasi, -1, struncode, len);
	
}
void CDexviewDlg::OnBnOpen() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	if (m_pfile)
	{
		fclose(m_pfile);
	}
	DexHeader header;
//	m_csfilename.GetBuffer(0);
	wchar_t szfilename[512] = {0};
	ConvertASIToUncode(m_csfilename.GetBuffer(0),szfilename);
//	swprintf(szfilename,L"%hs",);
	OpenDexFile(szfilename,&m_pfile);
	if (!m_pfile)
	{
		return;
	}
	ReadDexHeader(m_pfile,&header);
	m_treetype.DeleteAllItems();
	m_treetype.InsertItem("DexHeader",0,0);
	HTREEITEM item = m_treetype.GetRootItem();
	m_treetype.SetItemData(item,kDexTypeHeaderItem);
	item = m_treetype.InsertItem("DexStringId",0,0,m_treetype.GetRootItem());
	m_treetype.SetItemData(item,kDexTypeStringIdItem);
	item = m_treetype.InsertItem("typeIds",0,0,m_treetype.GetRootItem());
	m_treetype.SetItemData(item,kDexTypeTypeIdItem);
	item = m_treetype.InsertItem("fieldIds",0,0,m_treetype.GetRootItem());
	m_treetype.SetItemData(item,kDexTypeFieldIdItem);
	item = m_treetype.InsertItem("methodIds",0,0,m_treetype.GetRootItem());
	m_treetype.SetItemData(item,kDexTypeMethodIdItem);
	item = m_treetype.InsertItem("ProtoId",0,0,m_treetype.GetRootItem());
	m_treetype.SetItemData(item,kDexTypeProtoIdItem);
	item = m_treetype.InsertItem("ClassDef",0,0,m_treetype.GetRootItem());
	m_treetype.SetItemData(item,kDexTypeClassDefItem);
}

int CDexviewDlg::insertValue(int index,DWORD offset,char * valuename,char * pdata)
{
	char szOffset[100] = {0};
	sprintf(szOffset,"+%x",offset);
	m_listData.InsertItem(index,szOffset);
	m_listData.SetItemText(index,1,valuename);
	m_listData.SetItemText(index,2,pdata);
	return 0;
}

int CDexviewDlg::ShowDexStringId()
{
	DexHeader header;
	ReadDexHeader(m_pfile,&header);
	m_listData.DeleteAllItems();
	int ColumnCount = m_listData.GetHeaderCtrl()->GetItemCount();
	for (int i =ColumnCount-1;i>=0;i--)
	{
		m_listData.DeleteColumn(i);
	}	
	m_listData.InsertColumn(0,TEXT("index"),LVCFMT_LEFT,90);
//	m_listData.InsertColumn(1,TEXT("itemptr"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(1,TEXT("vaulesize"),LVCFMT_LEFT,90);
 	m_listData.InsertColumn(2,TEXT("vaule"),LVCFMT_LEFT,90);
	int CurrentIndex = 0;
//		for (int j =0;j<2;j++)
	for (int j =0;j<header.stringIdsSize;j++)
	{
		int nsize = 0;
		GetDexStringSize(m_pfile,j,&nsize);
		char *pbuffer  = 0;
		if (nsize)
		{
			pbuffer = (char*)malloc(nsize*2+1);
			GetDexString(m_pfile,j,pbuffer);
			InsertStringValue(CurrentIndex,j,nsize,pbuffer);
			free(pbuffer);
		}
	}
	return 0;
}
void ConvertUtf8ToASI(char* strUtf8)  
{
	int len=MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)strUtf8, -1, NULL,0);
	unsigned short * wszGBK = new unsigned short[len+1];
	memset(wszGBK, 0, len * 2 + 2);
	MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)strUtf8, -1, (LPWSTR)wszGBK, len);
	
	len = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)wszGBK, -1, NULL, 0, NULL, NULL);
	char *szGBK=new char[len + 1];
	memset(szGBK, 0, len + 1);
	WideCharToMultiByte (CP_ACP, 0, (LPWSTR)wszGBK, -1, szGBK, len, NULL,NULL);
	
	memcpy(strUtf8,szGBK,len+1);
	delete[] szGBK;
	delete[] wszGBK;
}

int CDexviewDlg::InsertStringValue(int CurrentIndex,int index,int valuesize,char *vaule)
{
	char szOffset[100] = {0};
	sprintf(szOffset,"%x(%d)",index,index);
	m_listData.InsertItem(CurrentIndex,szOffset);
	sprintf(szOffset,"%x",valuesize);
	m_listData.SetItemText(CurrentIndex,1,szOffset);
	ConvertUtf8ToASI(vaule);
	m_listData.SetItemText(CurrentIndex,2,vaule);
	return 0;
}

int CDexviewDlg::ShowDexTypeId()
{
	DexHeader header;
	ReadDexHeader(m_pfile,&header);
	m_listData.DeleteAllItems();
	int ColumnCount = m_listData.GetHeaderCtrl()->GetItemCount();
	for (int i =ColumnCount-1;i>=0;i--)
	{
		m_listData.DeleteColumn(i);
	}	
	m_listData.InsertColumn(0,TEXT("index"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(1,TEXT("descriptor"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(2,TEXT("descriptorIdx"),LVCFMT_LEFT,90);
	int CurrentIndex = 0;
	//		for (int j =0;j<2;j++)
	DexTypeId TypeId;
	for (int j =0;j<header.typeIdsSize;j++)
	{
		GetDexReadTypeIdData(m_pfile,j,&TypeId);
		insertTypeId(j,&TypeId);

	}
	return 0;
}
int CDexviewDlg::insertTypeId(int index,void * pdata)
{
	char szOffset[512] = {0};
	sprintf(szOffset,"+%x(%d)",index,index);
	m_listData.InsertItem(index,szOffset);
	GetDexString(m_pfile,((DexTypeId*)pdata)->descriptorIdx,szOffset);
//	sprintf(szOffset,"%x(%d)",((DexTypeId*)pdata)->descriptorIdx,((DexTypeId*)pdata)->descriptorIdx);
	m_listData.SetItemText(index,1,szOffset);
	sprintf(szOffset,"%x(%d)",((DexTypeId*)pdata)->descriptorIdx,((DexTypeId*)pdata)->descriptorIdx);
	m_listData.SetItemText(index,2,szOffset);
	return 0;
}
int CDexviewDlg::insertFieldId(int index,void * pdata)
{
	char szOffset[100] = {0};
	sprintf(szOffset,"+%x(%d)",index,index);
	m_listData.InsertItem(index,szOffset);
	GetDexString(m_pfile,((DexMethodId*)pdata)->nameIdx,szOffset);
	m_listData.SetItemText(index,1,szOffset);
	sprintf(szOffset,"%x(%d)",((DexFieldId*)pdata)->classIdx,
		((DexFieldId*)pdata)->classIdx);
	m_listData.SetItemText(index,2,szOffset);
	sprintf(szOffset,"%x(%d)",((DexFieldId*)pdata)->typeIdx,
		((DexFieldId*)pdata)->typeIdx);
	m_listData.SetItemText(index,3,szOffset);
	sprintf(szOffset,"%x(%d)",((DexFieldId*)pdata)->nameIdx,
		((DexFieldId*)pdata)->nameIdx);
	m_listData.SetItemText(index,4,szOffset);
	return 0;
}

int CDexviewDlg::ShowDexFieldId()
{
	DexHeader header;
	ReadDexHeader(m_pfile,&header);
	m_listData.DeleteAllItems();
	int ColumnCount = m_listData.GetHeaderCtrl()->GetItemCount();
	for (int i =ColumnCount-1;i>=0;i--)
	{
		m_listData.DeleteColumn(i);
	}	
	m_listData.InsertColumn(0,TEXT("name"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(1,TEXT("index"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(2,TEXT("classIdx"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(3,TEXT("typeIdx"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(4,TEXT("nameIdx"),LVCFMT_LEFT,90);
	int CurrentIndex = 0;
	//		for (int j =0;j<2;j++)
	DexFieldId FieldId;
	for (int j =0;j<header.fieldIdsSize;j++)
	{
		GetDexReadFieldId(m_pfile,j,&FieldId);
		insertFieldId(j,&FieldId);
	}
	return 0;
}
int CDexviewDlg::insertMethodId(int index,void * pdata)
{
	char szOffset[100] = {0};
	sprintf(szOffset,"+%x(%d)",index,index);
	m_listData.InsertItem(index,szOffset);
	sprintf(szOffset,"%x(%d)",((DexMethodId*)pdata)->classIdx,
		((DexMethodId*)pdata)->classIdx);
	m_listData.SetItemText(index,1,szOffset);
	sprintf(szOffset,"%x(%d)",((DexMethodId*)pdata)->protoIdx,
		((DexMethodId*)pdata)->protoIdx);
	m_listData.SetItemText(index,2,szOffset);
	sprintf(szOffset,"%x(%d)",((DexMethodId*)pdata)->nameIdx,
		((DexMethodId*)pdata)->nameIdx);
	m_listData.SetItemText(index,3,szOffset);
	return 0;
}

int CDexviewDlg::ShowDexMethodId()
{
	DexHeader header;
	ReadDexHeader(m_pfile,&header);
	m_listData.DeleteAllItems();
	int ColumnCount = m_listData.GetHeaderCtrl()->GetItemCount();
	for (int i =ColumnCount-1;i>=0;i--)
	{
		m_listData.DeleteColumn(i);
	}	
	m_listData.InsertColumn(0,TEXT("name"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(1,TEXT("index"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(2,TEXT("classIdx"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(3,TEXT("protoIdx"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(4,TEXT("nameIdx"),LVCFMT_LEFT,90);
	int CurrentIndex = 0;
	//		for (int j =0;j<2;j++)
	DexMethodId MethodId;
	for (int j =0;j<header.fieldIdsSize;j++)
	{
		GetDexReadmethodId(m_pfile,j,&MethodId);
		insertFieldId(j,&MethodId);
	}
	return 0;
}
int CDexviewDlg::ShowDexClassDef(HTREEITEM item)
{
	DexHeader header;
	ReadDexHeader(m_pfile,&header);
	m_listData.DeleteAllItems();
	int ColumnCount = m_listData.GetHeaderCtrl()->GetItemCount();
	for (int i =ColumnCount-1;i>=0;i--)
	{
		m_listData.DeleteColumn(i);
	}	
	m_listData.InsertColumn(0,TEXT("index"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(1,TEXT("classname"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(2,TEXT("classIdx"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(3,TEXT("accessFlags"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(4,TEXT("superclassIdx"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(5,TEXT("interfacesOff"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(6,TEXT("sourceFileIdx"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(7,TEXT("annotationsOff"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(8,TEXT("classDataOff"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(9,TEXT("staticValuesOff"),LVCFMT_LEFT,90);
	int CurrentIndex = 0;
	//		for (int j =0;j<2;j++)
	DexClassDef ClassDef;
	int j;
	for ( j =0;j<header.classDefsSize;j++)
	{
		GetDexReadClassDef(m_pfile,j,&ClassDef);
		insertClassDef(j,&ClassDef);
	}
	if (m_treetype.GetNextItem(item,TVGN_CHILD))
	{
		return 0;
	}
	for ( j =0;j<header.classDefsSize;j++)
	{
		GetDexReadClassDef(m_pfile,j,&ClassDef);
//		insertClassDef(j,&ClassDef);
		char szdata[512] ={0};
		TypeIdxToString(m_pfile,ClassDef.classIdx,szdata);
		//ClassDef.dexstrfromtypeid
		HTREEITEM subitem = m_treetype.InsertItem(szdata,0,0,item);
		m_treetype.SetItemData(subitem,kDexTypeClassDataItem);
	}
	return 0;
}
int CDexviewDlg::insertClassDef(int index,void * pdata)
{
	char szOffset[100] = {0};
	sprintf(szOffset,"+%x(%d)",index,index);
	m_listData.InsertItem(index,szOffset);
	TypeIdxToString(m_pfile,((DexClassDef*)pdata)->classIdx,szOffset);
	m_listData.SetItemText(index,1,szOffset);
	sprintf(szOffset,"%x(%d)",((DexClassDef*)pdata)->classIdx,
		((DexClassDef*)pdata)->classIdx);
	m_listData.SetItemText(index,2,szOffset);
	sprintf(szOffset,"%x(%d)",((DexClassDef*)pdata)->accessFlags,
		((DexClassDef*)pdata)->accessFlags);
	m_listData.SetItemText(index,3,szOffset);
	sprintf(szOffset,"%x(%d)",((DexClassDef*)pdata)->superclassIdx,
		((DexClassDef*)pdata)->superclassIdx);
	m_listData.SetItemText(index,4,szOffset);
	sprintf(szOffset,"%x(%d)",((DexClassDef*)pdata)->interfacesOff,
		((DexClassDef*)pdata)->interfacesOff);
	m_listData.SetItemText(index,5,szOffset);
	sprintf(szOffset,"%x(%d)",((DexClassDef*)pdata)->sourceFileIdx,
		((DexClassDef*)pdata)->sourceFileIdx);
	m_listData.SetItemText(index,6,szOffset);
	sprintf(szOffset,"%x(%d)",((DexClassDef*)pdata)->annotationsOff,
		((DexClassDef*)pdata)->annotationsOff);
	m_listData.SetItemText(index,7,szOffset);
	sprintf(szOffset,"%x(%d)",((DexClassDef*)pdata)->classDataOff,
		((DexClassDef*)pdata)->classDataOff);
	m_listData.SetItemText(index,8,szOffset);
	sprintf(szOffset,"%x(%d)",((DexClassDef*)pdata)->staticValuesOff,
		((DexClassDef*)pdata)->staticValuesOff);
	m_listData.SetItemText(index,9,szOffset);
	return 0;
}
int CDexviewDlg::ShowDexClassHeader(HTREEITEM item)
{
	DexHeader header;
//	DexClassDef ClassDef;
	ReadDexHeader(m_pfile,&header);
	m_listData.DeleteAllItems();
	int ColumnCount = m_listData.GetHeaderCtrl()->GetItemCount();
	for (int i =ColumnCount-1;i>=0;i--)
	{
		m_listData.DeleteColumn(i);
	}	
	m_listData.InsertColumn(0,TEXT("index"),LVCFMT_LEFT,90);
	//	m_listData.InsertColumn(1,TEXT("itemptr"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(1,TEXT("vaulename"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(2,TEXT("vaule"),LVCFMT_LEFT,90);
	HTREEITEM hParent = m_treetype.GetParentItem(item);
	int index = GetItemIndexFormParent(hParent,item);
	DexClassDef ClassDef;
	DexClassDataHeader ClassDataHeader;
	GetDexReadClassDef(m_pfile,index,&ClassDef);
	GetClassDataHeader(m_pfile,index,&ClassDataHeader);
	insertClassDef(index,&ClassDataHeader);
	if (index>=0)
	{
		insertClassData(item,&ClassDataHeader);
	}
	//		for (int j =0;j<2;j++)

	return 0;
}
int CDexviewDlg::insertClassData(HTREEITEM item,void *pheader)
//DexClassDataHeader
{
	DexClassDataHeader *classdata= (DexClassDataHeader *)pheader;
	char szOffset[100] = {0};
	int index = 0;
	sprintf(szOffset,"%d",classdata->staticFieldsSize);
	insertValue(0,0,"staticFieldsSize",szOffset);
	sprintf(szOffset,"%d",classdata->instanceFieldsSize);
	insertValue(1,0,"instanceFieldsSize",szOffset);
	sprintf(szOffset,"%d",classdata->directMethodsSize);
	insertValue(2,0,"directMethodsSize",szOffset);
	sprintf(szOffset,"%d",classdata->virtualMethodsSize);
	insertValue(3,0,"virtualMethodsSize",szOffset);
	if (m_treetype.GetNextItem(item,TVGN_CHILD))
	{
	return 0;
	}
	HTREEITEM subitem = m_treetype.InsertItem("staticFields",0,0,item);
	m_treetype.SetItemData(subitem,kDexTypestaticFieldItem);
	subitem =m_treetype.InsertItem("instanceFields",0,0,item);
	m_treetype.SetItemData(subitem,kDexTypeinstanceFieldItem);
	subitem =m_treetype.InsertItem("directMethods",0,0,item);
	m_treetype.SetItemData(subitem,kDexTypedirectMethodItem);
	subitem =m_treetype.InsertItem("virtualMethods",0,0,item);
	m_treetype.SetItemData(subitem,kDexTypevirtualMethodItem);
	return 0;
}
int CDexviewDlg::GetItemIndexFormParent(HTREEITEM hParent,HTREEITEM item)
{
	HTREEITEM hcurrent = m_treetype.GetChildItem(hParent);
	int nindex = -1;
	if (hcurrent>0)
	{
		nindex ++;
		for (;hcurrent!=item;nindex++)
		{
			hcurrent = m_treetype.GetNextItem(hcurrent,TVGN_NEXT);
		}	
	}
	return nindex;
}
int CDexviewDlg::ShowStaticField(HTREEITEM item)
{
	DexHeader header;
	//	DexClassDef ClassDef;
	
	HTREEITEM l1item = m_treetype.GetNextItem(item,TVGN_PARENT);
	DWORD dwdata = m_treetype.GetItemData(l1item);
	if (dwdata!= kDexTypeClassDataItem)
	{
		return 0;
	}
	HTREEITEM l2item = m_treetype.GetNextItem(l1item,TVGN_PARENT);
	dwdata = m_treetype.GetItemData(l2item);
	if (dwdata!= kDexTypeClassDefItem)
	{
		return 0;
	}
	ReadDexHeader(m_pfile,&header);
	m_listData.DeleteAllItems();
	int ColumnCount = m_listData.GetHeaderCtrl()->GetItemCount();
	for (int i =ColumnCount-1;i>=0;i--)
	{
		m_listData.DeleteColumn(i);
	}	
	m_listData.InsertColumn(0,TEXT("fieldIdx"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(1,TEXT("accessFlags"),LVCFMT_LEFT,90);
	//	m_listData.InsertColumn(1,TEXT("vaulename"),LVCFMT_LEFT,90);
	//	m_listData.InsertColumn(2,TEXT("vaule"),LVCFMT_LEFT,90);
	HTREEITEM hParent = l2item;
	int index = GetItemIndexFormParent(hParent,l1item);
	if (index>=0)
	{
		DexClassDef ClassDef;
		DexClassDataHeader ClassDataHeader;
		DexField Field;
		GetDexReadClassDef(m_pfile,index,&ClassDef);
		GetClassDataHeader(m_pfile,index,&ClassDataHeader);
		u4 lastfieldIdx = 0;
		int nstartoffset =0;
		for (int i =0;i<ClassDataHeader.staticFieldsSize;i++)
		{
			int nsize =GetClassDataField(m_pfile,nstartoffset,index,0,&Field);
			nstartoffset+=nsize;
			InsertClassDataField(i,&Field,lastfieldIdx);
			lastfieldIdx+=Field.fieldIdx;
		}
	}
	return 0;
}
int CDexviewDlg::ShowInstanceField(HTREEITEM item)
{
	DexHeader header;
	//	DexClassDef ClassDef;
	
	HTREEITEM l1item = m_treetype.GetNextItem(item,TVGN_PARENT);
	DWORD dwdata = m_treetype.GetItemData(l1item);
	if (dwdata!= kDexTypeClassDataItem)
	{
		return 0;
	}
	HTREEITEM l2item = m_treetype.GetNextItem(l1item,TVGN_PARENT);
	dwdata = m_treetype.GetItemData(l2item);
	if (dwdata!= kDexTypeClassDefItem)
	{
		return 0;
	}
	ReadDexHeader(m_pfile,&header);
	m_listData.DeleteAllItems();
	int ColumnCount = m_listData.GetHeaderCtrl()->GetItemCount();
	for (int i =ColumnCount-1;i>=0;i--)
	{
		m_listData.DeleteColumn(i);
	}	
	m_listData.InsertColumn(0,TEXT("fieldIdx"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(1,TEXT("accessFlags"),LVCFMT_LEFT,90);
	//	m_listData.InsertColumn(0,TEXT("index"),LVCFMT_LEFT,90);
	//	m_listData.InsertColumn(1,TEXT("itemptr"),LVCFMT_LEFT,90);
	//	m_listData.InsertColumn(1,TEXT("vaulename"),LVCFMT_LEFT,90);
	//	m_listData.InsertColumn(2,TEXT("vaule"),LVCFMT_LEFT,90);
	HTREEITEM hParent = l2item;
	int index = GetItemIndexFormParent(hParent,l1item);
	if (index>=0)
	{
		DexClassDef ClassDef;
		DexClassDataHeader ClassDataHeader;
		DexField Field;
		GetDexReadClassDef(m_pfile,index,&ClassDef);
		GetClassDataHeader(m_pfile,index,&ClassDataHeader);
		u4 lastfieldIdx = 0;
		int nstartoffset=0;
		int i =0;
		for ( i = 0;i<ClassDataHeader.staticFieldsSize;i++)
		{
			int nsize = GetClassDataFieldSize(m_pfile,nstartoffset,index);
			nstartoffset+=nsize;
		}
//		nstartoffset = sizeof(DexField)*ClassDataHeader.staticFieldsSize;
		for ( i =0;i<ClassDataHeader.instanceFieldsSize;i++)
		{
			int nsize = GetClassDataField(m_pfile,nstartoffset,index,0,&Field);
			nstartoffset+=nsize;
			InsertClassDataField(i,&Field,lastfieldIdx);
			lastfieldIdx+=Field.fieldIdx;
		}
	}
	//		for (int j =0;j<2;j++)
	
	return 0;
}
int CDexviewDlg::InsertClassDataField(int index,void *pdata,u4 lastfieldIdx)
{
	DexField *Field =(DexField *)pdata;
	char szOffset[100] = {0};
	sprintf(szOffset,"%d",Field->fieldIdx+lastfieldIdx);
	m_listData.InsertItem(index,szOffset);
//	insertValue(0,0,"staticFieldsSize",szOffset);
	sprintf(szOffset,"%x",Field->accessFlags);
	m_listData.SetItemText(index,1,szOffset);
//	insertValue(1,0,"instanceFieldsSize",szOffset);
	return 0;
}


int CDexviewDlg::ShowDirectMethod(HTREEITEM item)
{
	DexHeader header;
	//	DexClassDef ClassDef;
	
	HTREEITEM l1item = m_treetype.GetNextItem(item,TVGN_PARENT);
	DWORD dwdata = m_treetype.GetItemData(l1item);
	if (dwdata!= kDexTypeClassDataItem)
	{
		return 0;
	}
	HTREEITEM l2item = m_treetype.GetNextItem(l1item,TVGN_PARENT);
	dwdata = m_treetype.GetItemData(l2item);
	if (dwdata!= kDexTypeClassDefItem)
	{
		return 0;
	}
	ReadDexHeader(m_pfile,&header);
	m_listData.DeleteAllItems();
	int ColumnCount = m_listData.GetHeaderCtrl()->GetItemCount();
	for (int i =ColumnCount-1;i>=0;i--)
	{
		m_listData.DeleteColumn(i);
	}	
	m_listData.InsertColumn(0,TEXT("methodname"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(1,TEXT("methodIdx"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(2,TEXT("accessFlags"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(3,TEXT("codeOff"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(4,TEXT("registersSize"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(5,TEXT("insSize"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(6,TEXT("outsSize"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(7,TEXT("triesSize"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(8,TEXT("debugInfoOff"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(9,TEXT("insnsSize"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(10,TEXT("methodcode"),LVCFMT_LEFT,90);
	//	m_listData.InsertColumn(1,TEXT("vaulename"),LVCFMT_LEFT,90);
	//	m_listData.InsertColumn(2,TEXT("vaule"),LVCFMT_LEFT,90);
	HTREEITEM hParent = l2item;
	int index = GetItemIndexFormParent(hParent,l1item);
	if (index>=0)
	{
		DexClassDef ClassDef;
		DexClassDataHeader ClassDataHeader;
		DexMethod Method;
		GetDexReadClassDef(m_pfile,index,&ClassDef);
		GetClassDataHeader(m_pfile,index,&ClassDataHeader);
		u4 lastfieldIdx = 0;
		int nstartoffset =0;
		int i =0;
		for ( i = 0;i<ClassDataHeader.staticFieldsSize;i++)
		{
			int nsize = GetClassDataFieldSize(m_pfile,nstartoffset,index);
			nstartoffset+=nsize;
		}
		for ( i = 0;i<ClassDataHeader.instanceFieldsSize;i++)
		{
			int nsize = GetClassDataFieldSize(m_pfile,nstartoffset,index);
			nstartoffset+=nsize;
		}
// 		nstartoffset = sizeof(DexField)*ClassDataHeader.staticFieldsSize;
// 		nstartoffset += sizeof(DexField)*ClassDataHeader.instanceFieldsSize;
		DexCode code;
		for (i =0;i<ClassDataHeader.directMethodsSize;i++)
		{
			int nsize = GetClassDataMethod(m_pfile,nstartoffset,index,0,&Method);
			GetClassDexCODE(m_pfile,&Method,&code);
			nstartoffset+=nsize;
			InsertClassDataMethodAndCode(i,&Method,&code,lastfieldIdx);
			lastfieldIdx+=Method.methodIdx;
		}
	}
	return 0;
}
int CDexviewDlg::InsertClassDataMethod(int index,void *ppMethod,u4 lastfieldIdx)
{
	DexMethod *pMethod =(DexMethod *)ppMethod;
	char szOffset[100] = {0};
	sprintf(szOffset,"%d",pMethod->methodIdx+lastfieldIdx);
	m_listData.InsertItem(index,szOffset);
	//	insertValue(0,0,"staticFieldsSize",szOffset);
	sprintf(szOffset,"%x",pMethod->accessFlags);
	m_listData.SetItemText(index,1,szOffset);
	sprintf(szOffset,"%x",pMethod->codeOff);
	m_listData.SetItemText(index,2,szOffset);
	//	insertValue(1,0,"instanceFieldsSize",szOffset);
	return 0;
}
int CDexviewDlg::InsertClassDataMethodAndCode(int index,void *ppMethod,void * ppcode,u4 lastfieldIdx)
{
	DexMethod *pMethod =(DexMethod *)ppMethod;
	DexMethodId MethodId;
	DexCode *pcode =(DexCode *)ppcode;
	char szOffset[100] = {0};
	GetDexReadmethodId(m_pfile,pMethod->methodIdx+lastfieldIdx,&MethodId);
	GetDexString(m_pfile,MethodId.nameIdx,szOffset);
	m_listData.InsertItem(index,szOffset);
	//	insertValue(0,0,"staticFieldsSize",szOffset);
	sprintf(szOffset,"%x",pMethod->methodIdx+lastfieldIdx);
	m_listData.SetItemText(index,1,szOffset);
	sprintf(szOffset,"%x",pMethod->accessFlags);
	m_listData.SetItemText(index,2,szOffset);
	sprintf(szOffset,"%x",pMethod->codeOff);
	m_listData.SetItemText(index,3,szOffset);
	if(pMethod->codeOff)
	{
		sprintf(szOffset,"%x",pcode->registersSize);
		m_listData.SetItemText(index,4,szOffset);
		sprintf(szOffset,"%x",pcode->insSize);
		m_listData.SetItemText(index,5,szOffset);
		sprintf(szOffset,"%x",pcode->outsSize);
		m_listData.SetItemText(index,6,szOffset);
		sprintf(szOffset,"%x",pcode->triesSize);
		m_listData.SetItemText(index,7,szOffset);
		sprintf(szOffset,"%x",pcode->debugInfoOff);
		m_listData.SetItemText(index,8,szOffset);
		sprintf(szOffset,"%x",pcode->insnsSize);
		m_listData.SetItemText(index,9,szOffset);
		unsigned int codeoff= ((unsigned int)&pcode->insns[0])-((unsigned int)pcode)+pMethod->codeOff;
		sprintf(szOffset,"%x",codeoff);
		m_listData.SetItemText(index,10,szOffset);

	}
	//	insertValue(1,0,"instanceFieldsSize",szOffset);
	return 0;
}
int CDexviewDlg::ShowVirtualMethod(HTREEITEM item)
{
	DexHeader header;
	//	DexClassDef ClassDef;
	
	HTREEITEM l1item = m_treetype.GetNextItem(item,TVGN_PARENT);
	DWORD dwdata = m_treetype.GetItemData(l1item);
	if (dwdata!= kDexTypeClassDataItem)
	{
		return 0;
	}
	HTREEITEM l2item = m_treetype.GetNextItem(l1item,TVGN_PARENT);
	dwdata = m_treetype.GetItemData(l2item);
	if (dwdata!= kDexTypeClassDefItem)
	{
		return 0;
	}
	ReadDexHeader(m_pfile,&header);
	m_listData.DeleteAllItems();
	int ColumnCount = m_listData.GetHeaderCtrl()->GetItemCount();
	for (int i =ColumnCount-1;i>=0;i--)
	{
		m_listData.DeleteColumn(i);
	}	
	m_listData.InsertColumn(0,TEXT("methodname"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(1,TEXT("methodIdx"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(2,TEXT("accessFlags"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(3,TEXT("codeOff"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(4,TEXT("registersSize"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(5,TEXT("insSize"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(6,TEXT("outsSize"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(7,TEXT("triesSize"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(8,TEXT("debugInfoOff"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(9,TEXT("insnsSize"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(10,TEXT("methodcode"),LVCFMT_LEFT,90);
	//	m_listData.InsertColumn(1,TEXT("vaulename"),LVCFMT_LEFT,90);
	//	m_listData.InsertColumn(2,TEXT("vaule"),LVCFMT_LEFT,90);
	HTREEITEM hParent = l2item;
	int index = GetItemIndexFormParent(hParent,l1item);
	if (index>=0)
	{
		DexClassDef ClassDef;
		DexClassDataHeader ClassDataHeader;
		DexMethod Method;
		GetDexReadClassDef(m_pfile,index,&ClassDef);
		GetClassDataHeader(m_pfile,index,&ClassDataHeader);
		u4 lastfieldIdx = 0;
		int nstartoffset =0;
		int i =0;
		for ( i = 0;i<ClassDataHeader.staticFieldsSize;i++)
		{
			int nsize = GetClassDataFieldSize(m_pfile,nstartoffset,index);
			nstartoffset+=nsize;
		}
		for ( i = 0;i<ClassDataHeader.instanceFieldsSize;i++)
		{
			int nsize = GetClassDataFieldSize(m_pfile,nstartoffset,index);
			nstartoffset+=nsize;
		}
		for ( i = 0;i<ClassDataHeader.directMethodsSize;i++)
		{
			int nsize = GetClassDataMethodSize(m_pfile,nstartoffset,index);
			nstartoffset+=nsize;
		}
// 		nstartoffset = sizeof(DexField)*ClassDataHeader.staticFieldsSize;
// 		nstartoffset += sizeof(DexField)*ClassDataHeader.instanceFieldsSize;
		// 		nstartoffset += sizeof(DexField)*ClassDataHeader.directMethodsSize;
		DexCode code;
		for ( i =0;i<ClassDataHeader.virtualMethodsSize;i++)
		{
			int nsize = GetClassDataMethod(m_pfile,nstartoffset,index,0,&Method);
			GetClassDexCODE(m_pfile,&Method,&code);
			nstartoffset+=nsize;
			InsertClassDataMethodAndCode(i,&Method,&code,lastfieldIdx);
			lastfieldIdx+=Method.methodIdx;
		}
	}
	return 0;
}
int CDexviewDlg::ShowDexProtoId()
{
	DexHeader header;
	ReadDexHeader(m_pfile,&header);
	m_listData.DeleteAllItems();
	int ColumnCount = m_listData.GetHeaderCtrl()->GetItemCount();
	for (int i =ColumnCount-1;i>=0;i--)
	{
		m_listData.DeleteColumn(i);
	}	
	m_listData.InsertColumn(0,TEXT("index"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(1,TEXT("shortyIdx"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(2,TEXT("returnTypeIdx"),LVCFMT_LEFT,90);
	m_listData.InsertColumn(3,TEXT("parametersOff"),LVCFMT_LEFT,90);
	int CurrentIndex = 0;
	//		for (int j =0;j<2;j++)
	DexProtoId ProtoId;
	for (int j =0;j<header.protoIdsSize;j++)
	{
		GetDexReadProtoId(m_pfile,j,&ProtoId);
		insertProtoId(j,&ProtoId);
	}
	return 0;
}
int CDexviewDlg::insertProtoId(int index,void * pdata)
{
	char szOffset[100] = {0};
	sprintf(szOffset,"+%x(%d)",index,index);
	m_listData.InsertItem(index,szOffset);
	sprintf(szOffset,"%x(%d)",((DexProtoId*)pdata)->shortyIdx,
		((DexProtoId*)pdata)->shortyIdx);
	m_listData.SetItemText(index,1,szOffset);
	sprintf(szOffset,"%x(%d)",((DexProtoId*)pdata)->returnTypeIdx,
		((DexProtoId*)pdata)->returnTypeIdx);
	m_listData.SetItemText(index,2,szOffset);
	sprintf(szOffset,"%x(%d)",((DexProtoId*)pdata)->parametersOff,
		((DexProtoId*)pdata)->parametersOff);
	m_listData.SetItemText(index,3,szOffset);
	return 0;
}

void CDexviewDlg::OnBNClose() 
{
	// TODO: Add your control notification handler code here
	
	UpdateData(TRUE);
	if (m_pfile)
	{
		fclose(m_pfile);
	}
	m_treetype.DeleteAllItems();
	UpdateData(FALSE);
}
